﻿#include "Measure_Rect.h"
#include "qdebug.h"
Measure_Rect::Measure_Rect()
{

}

int Measure_Rect::M_Rect(HObject Img,int M_Model,bool Direction,int CCDNum,HTuple &OutPara,HObject &OutImg)
{
    int flag=0;
    OutPara.Clear();


    HObject  Region, FRegion, RegionTrans, RegionDifference, Rectangle1, ImageReduced1, Region1;
    HObject  ImageResult1, Edges1, ERegion1, EndPoints1;
    HObject  JuncPoints1, ConnectedRegions1;
    HObject  Rectangle2;
    HObject  ImageReduced2, Region2, ImageResult2, Edges2;
    HObject  ERegion2, EndPoints2, JuncPoints2, ConnectedRegions2;


    HTuple Value;
    HTuple  Row, Column, Phi, W, H, r1, c1;
    HTuple  line1, line2, r2, c2, line3, line4;
    HTuple  MetrologyHandle1, Index1, Line1;
    HTuple  MetrologyHandle2, Line2, MetrologyHandle3;
    HTuple  Line3, MetrologyHandle4;
    HTuple  Line4, Distance1, Distance2, Distance3;
    HTuple  Distance4, Len1, Len2, Angle1, Angle2;
    HTuple  OutPara1,OutPara2;
    HTuple  h,w;
    float h1,w1;
    Flag1=true;
    Flag2=true;
    Flag3=true;
    Flag4=true;


    //    //4号相机
    //    //垂直
    //    float para1=0.007050173;
    //    //水平
    //    float para2=para1-0.000099876;




    //1号相机
    //垂直
    float para1 = m_part.para1;

    //水平


    //——————————————————————垂直方向
    //补偿值
    float para3 = m_part.para3;
    //标准值
    float para4 =  m_part.para4;
    //上限值
    float para5 =  m_part.para5;
    //下限值
    float para6 = m_part.para6;
    //平行度补偿值
    float para7 = m_part.para7;
    //平行度标准值
    float para8 = m_part.para8;
    //平行度偏差值
    float para9 = m_part.para9;


    //——————————————————————水平方向
    //补偿值
    float para10 = m_part.para10;
    //标准值
    float para11 = m_part.para11;
    //上限值
    float para12 = m_part.para12;
    //下限值
    float para13 = m_part.para13;
    //平行度补偿值
    float para14 = m_part.para14;
    //平行度标准值
    float para15 = m_part.para15;
    //平行度偏差值
    float para16 = m_part.para16;

    //------------------图像处理

    //粗定定位阈值
    float para17 = m_part.para17;
    //找边向外沿伸长度
    float para18 = m_part.para18;
    //找边sigma
    float para19 = m_part.para19;
    //找边阈值
    float para20 = m_part.para20;


    float para2=0;

    if(CCDNum==1)
    {
        //水平方向
        para2=para1-0.00006244;
        qDebug()<<para2;



    }
    else if(CCDNum==4)
    {
        para2=para1-0.00008921;
    }
    else
    {
        para2=0;
    }
    try
    {
        OutImg=Img;
        /*
        Threshold(Img, &Region11, 0, 230);
        Connection(Region11, &Region11);
*/

        Threshold(Img, &Region, 0, para17);


        Connection(Region, &Region);
        //        SelectShape(Region, &Region, (HTuple("area").Append("row").Append("column").Append("width")),
        //                    "and", (HTuple(10000).Append(500).Append(500).Append(100)), (HTuple(400000).Append(1600).Append(1850).Append(1000)));
        SelectShape(Region, &Region, (HTuple("area")),
                    "and", (HTuple(10000)), (HTuple(999900000)));
        if((M_Model==0))
        {
            RegionFeatures(Region,"height",&h);
            RegionFeatures(Region,"width",&w);
            h1= h*para1;
            w1= w*para2;
            if((h1<para4-0.1)||(w1<para11-0.1))
            {
                flag=1;
                return flag;
            }

        }



        Union1(Region, &Region);
        FillUp(Region, &FRegion);
        Difference(FRegion,Region, &RegionDifference);
        PaintRegion(RegionDifference,Img,&Img,0,"fill");
        if(Direction)
        {
            ShapeTrans (RegionDifference, &RegionTrans, "rectangle1");
            RegionFeatures (RegionTrans, "area", &Value);
            if(Value.D()<200000)
            {
                if(M_Model==0)
                {
                    OutPara.Append(0).Append(0).Append(0).Append(0);
                }
                else
                {
                    OutPara.Append(0).Append(0);
                }
                return flag;
            }
        }
        SmallestRectangle2(Region, &Row, &Column, &Phi, &W, &H);
        if((Phi>PI/2)&&(Phi<PI/2))
        {
            Phi=Phi-PI/2;
        }
        else if((-PI/4<=Phi)&&(Phi<0))
        {
            Phi=Phi+PI;
        }
        else if((0<=Phi)&&(Phi<=PI/4))
        {
            Phi=Phi;
        }
        else
        {
            Phi=Phi+PI/2;
        }

        //测试垂直高度
        if((M_Model==1)||(M_Model==0))
        {
            GenRectangle2(&Rectangle1, Row, Column, Phi, W/2, H+60);
            ReduceDomain(Img, Rectangle1, &ImageReduced1);
            Threshold(ImageReduced1, &Region1, 0, para17);
            Connection (Region1, &Region1);
            //            SelectShape(Region1, &Region1, (HTuple("area").Append("row").Append("column").Append("width")),
            //                        "and", (HTuple(300).Append(500).Append(500).Append(100)), (HTuple(900000).Append(1600).Append(1850).Append(1000)));
            SelectShape(Region1, &Region1, (HTuple("area")),
                        "and", (HTuple(300)), (HTuple(999900000)));
            Union1(Region1, &Region1);
            FillUp(Region1, &Region1);
            ShapeTrans(Region1, &Region1, "rectangle2");
            DilationRectangle1(Region1, &Region1, para18, para18);
            PaintRegion(Region1, ImageReduced1, &ImageResult1, 0, "fill");
            EdgesSubPix(ImageResult1, &Edges1, "canny", 3, 20, 40);
            SelectContoursXld(Edges1, &Edges1, "contour_length", 100, 20000, -0.5,
                              0.5);
            GenRegionContourXld(Edges1, &ERegion1, "filled");

            SelectShape(ERegion1, &ERegion1, (HTuple("width")),
                        "and", W-30, W+30);

            JunctionsSkeleton(ERegion1, &EndPoints1, &JuncPoints1);
            Connection(EndPoints1, &ConnectedRegions1);
            RegionFeatures(ConnectedRegions1, "row", &r1);
            RegionFeatures(ConnectedRegions1, "column", &c1);
            line1.Clear();
            line1.Append(HTuple(r1[0])).Append(HTuple(c1[0])).Append(HTuple(r1[1])).Append(HTuple(c1[1]));
            line2.Clear();
            line2.Append(HTuple(r1[2])).Append(HTuple(c1[2])).Append(HTuple(r1[3])).Append(HTuple(c1[3]));


            //线1
            CreateMetrologyModel(&MetrologyHandle1);
            AddMetrologyObjectLineMeasure(MetrologyHandle1, HTuple(line1[0]), HTuple(line1[1]),
                    HTuple(line1[2]), HTuple(line1[3]), 20, 5, para19, para20, HTuple(),
                    HTuple(), &Index1);
            ApplyMetrologyModel(Img, MetrologyHandle1);
            GetMetrologyObjectResult(MetrologyHandle1, "all", "all", "result_type",
                                     "all_param", &Line1);
            ClearMetrologyModel(MetrologyHandle1);
            //线2
            CreateMetrologyModel(&MetrologyHandle2);
            AddMetrologyObjectLineMeasure(MetrologyHandle2, HTuple(line2[0]), HTuple(line2[1]),
                    HTuple(line2[2]), HTuple(line2[3]), 20, 5, para19, para20, HTuple(),
                    HTuple(), &Index1);
            ApplyMetrologyModel(Img, MetrologyHandle2);
            GetMetrologyObjectResult(MetrologyHandle2, "all", "all", "result_type",
                                     "all_param", &Line2);
            ClearMetrologyModel(MetrologyHandle2);

            DistancePl(HTuple(Line1[0]), HTuple(Line1[1]), HTuple(Line2[0]), HTuple(Line2[1]),
                    HTuple(Line2[2]), HTuple(Line2[3]), &Distance1);
            DistancePl(HTuple(Line1[2]), HTuple(Line1[3]), HTuple(Line2[0]), HTuple(Line2[1]),
                    HTuple(Line2[2]), HTuple(Line2[3]), &Distance2);

            //（高度）
            Len1 = (Distance1+Distance2)/2;
            qDebug()<<Len1.D();
            Len1 = Len1*para1+para3;

            //短边
            if(!(((Len1)>(para4-para6))&&((Len1)<(para4+para5))))
            {
                Flag1=false;
                flag=1;
            }
            //平行度
            AngleLl(HTuple(Line1[0]), HTuple(Line1[1]), HTuple(Line1[2]), HTuple(Line1[3]),
                    HTuple(Line2[0]), HTuple(Line2[1]), HTuple(Line2[2]), HTuple(Line2[3]),
                    &Angle1);
            Angle1 = ((Angle1*180)/PI).TupleAbs()+para7;
            if(!(Angle1<(para8+para9)))
            {
                Flag2=false;
                flag=1;
            }
            TupleConcat (Len1, Angle1, &OutPara1);
        }
        //        测试水平长度
        if((M_Model==2)||(M_Model==0))
        {
            if((Phi<PI/2)||(Phi>PI*3/4))
            {
                Phi=Phi+PI/2;
            }
            GenRectangle2(&Rectangle2, Row, Column, Phi, H/2,
                          W+60);
            ReduceDomain(Img, Rectangle2, &ImageReduced2);
            Threshold(ImageReduced2, &Region2, 0, para17);
            //            SelectShape(Region2, &Region2, (HTuple("area").Append("row").Append("column").Append("width")),
            //                        "and", (HTuple(300).Append(500).Append(500).Append(100)), (HTuple(900000).Append(1600).Append(1850).Append(1000)));
            SelectShape(Region2, &Region2, (HTuple("area")),
                        "and", (HTuple(300)), (HTuple(999900000)));

            Connection(Region2, &Region2);
            FillUp(Region2, &Region2);
            ShapeTrans(Region2, &Region2, "rectangle2");
            DilationRectangle1(Region2, &Region2, para18, para18);
            PaintRegion(Region2, ImageReduced2, &ImageResult2, 0, "fill");
            EdgesSubPix(ImageResult2, &Edges2, "canny", 3, 20, 40);
            SelectContoursXld(Edges2, &Edges2, "contour_length", 100, 20000, -0.5,
                              0.5);
            GenRegionContourXld(Edges2, &ERegion2, "filled");


            SelectShape(ERegion2, &ERegion2, (HTuple("height")),
                        "and", H-30, H+30);

            JunctionsSkeleton(ERegion2, &EndPoints2, &JuncPoints2);
            Connection(EndPoints2, &ConnectedRegions2);
            RegionFeatures(ConnectedRegions2, "row", &r2);
            RegionFeatures(ConnectedRegions2, "column", &c2);

            line3.Clear();
            line3.Append(HTuple(r2[0])).Append(HTuple(c2[0])).Append(HTuple(r2[1])).Append(HTuple(c2[1]));
            line4.Clear();
            line4.Append(HTuple(r2[2])).Append(HTuple(c2[2])).Append(HTuple(r2[3])).Append(HTuple(c2[3]));
            //线3
            CreateMetrologyModel(&MetrologyHandle3);
            AddMetrologyObjectLineMeasure(MetrologyHandle3, HTuple(line3[0]), HTuple(line3[1]),
                    HTuple(line3[2]), HTuple(line3[3]), 20, 5, para19, para20, HTuple(),
                    HTuple(), &Index1);
            ApplyMetrologyModel(Img, MetrologyHandle3);
            GetMetrologyObjectResult(MetrologyHandle3, "all", "all", "result_type",
                                     "all_param", &Line3);
            ClearMetrologyModel(MetrologyHandle3);
            //线4
            CreateMetrologyModel(&MetrologyHandle4);
            AddMetrologyObjectLineMeasure(MetrologyHandle4, HTuple(line4[0]), HTuple(line4[1]),
                    HTuple(line4[2]), HTuple(line4[3]), 20, 5, para19, para20, HTuple(),
                    HTuple(), &Index1);
            ApplyMetrologyModel(Img, MetrologyHandle4);
            GetMetrologyObjectResult(MetrologyHandle4, "all", "all", "result_type",
                                     "all_param", &Line4);
            ClearMetrologyModel(MetrologyHandle4);

            //计算边长

            DistancePl(HTuple(Line3[0]), HTuple(Line3[1]), HTuple(Line4[0]), HTuple(Line4[1]),
                    HTuple(Line4[2]), HTuple(Line4[3]), &Distance3);
            DistancePl(HTuple(Line3[2]), HTuple(Line3[3]), HTuple(Line4[0]), HTuple(Line4[1]),
                    HTuple(Line4[2]), HTuple(Line4[3]), &Distance4);

            //长边
            Len2 = (Distance3+Distance4)/2;


            Len2 = Len2*para2+para10;

            //长边

            if(!(((Len2)>(para11-para13))&&((Len2)<(para11+para12))))
            {
                Flag3=false;
                flag=1;
            }
            AngleLl(HTuple(Line3[0]), HTuple(Line3[1]), HTuple(Line3[2]), HTuple(Line3[3]),
                    HTuple(Line4[0]), HTuple(Line4[1]), HTuple(Line4[2]), HTuple(Line4[3]),
                    &Angle2);
            Angle2 = ((Angle2*180)/PI).TupleAbs()+para14;
            if(!(Angle2<(para15+para16)))
            {
                Flag4=false;
                flag=1;
            }
            TupleConcat (Len2, Angle2, &OutPara2);
        }

        if(M_Model==1)
        {
            OutPara=OutPara1;
        }
        else if(M_Model==2)
        {
            OutPara=OutPara2;
        }
        else
        {
            TupleConcat (OutPara1, OutPara2, &OutPara2);
            OutPara=OutPara2;
        }
        qDebug()<<flag;
        //    qDebug()<<OutPara[0].D()<<OutPara[1].D()<<OutPara[2].D()<<"...............";
        return flag;

    }
    catch(HException &exception)
    {
        flag=-1;
        if(M_Model==0)
        {
            OutPara.Append(0).Append(0).Append(0).Append(0);
        }
        else
        {
            OutPara.Append(0).Append(0);
        }
        Flag1=false;
        Flag2=false;
        Flag3=false;
        Flag4=false;
        return flag;
    }

}
